package cn.yesway.common.utils;

import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

/**
 * 
 * DES加密器.
 * <p>
 * DES加密解密方法封装
 * 
 * 把byte转换为16进制字符串
 */
public class DES {
	private String algorithm = "DES";
	private KeyGenerator keygen;
	private SecretKey deskey;
	private Cipher cipher;
	private byte[] cipherByte;

	/**
	 * 初始化 DES 实例
	 */
	public DES() {
		init();
	}

	/**
	 * 根据原始密匙进行初始化DES实例
	 * 
	 * @param keyWords 原始密匙
	 */
	public DES(String keyWords) {
		init(keyWords);
	}

	/**
	 * 初始化DES
	 * 
	 * @param keyWords 原始密匙，如果为null则自动产生密匙
	 */
	public void init(String keyWords) {
		Security.addProvider(new com.sun.crypto.provider.SunJCE());
		try {
			// 如果原始密匙为空,这自动产生密匙
			if (keyWords == null) {
				keygen = KeyGenerator.getInstance(algorithm);
				deskey = keygen.generateKey();

			}
			else {
				// 获取加密密匙
				DESKeySpec desKeySpec = new DESKeySpec(keyWords.getBytes("UTF-8"));
				SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
				deskey = keyFactory.generateSecret(desKeySpec);
			}
			cipher = Cipher.getInstance(algorithm);
		}
		catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public void init() {
		init(null);
	}

	/**
	 * 对 String 进行加密
	 * 
	 * @param str 要加密的数据
	 * @return 返回加密后的 byte 数组
	 */
	public byte[] encryptByte(String str) {
		try {
			cipher.init(Cipher.ENCRYPT_MODE, deskey);
			cipherByte = cipher.doFinal(str.getBytes());
		}
		catch (Exception e) {
			throw new RuntimeException(e);
		}
		return cipherByte;
	}

	/**
	 * 对 String 进行加密
	 * 
	 * @param in 要加密的数据
	 * @return 返回加密后的16进制字符串
	 */
	public String encrypt(String in) {
		byte[] mid = encryptByte(in);

		String out = byteTohex(mid);
		return out;
	}

	/**
	 * 对 Byte 数组进行解密
	 * 
	 * @param buff 要解密的数据
	 * @return 返回解密后的 String
	 */
	public String decyptByte(byte[] buff) {
		try {
			cipher.init(Cipher.DECRYPT_MODE, deskey);
			cipherByte = cipher.doFinal(buff);
		}
		catch (Exception e) {
			// logger.error("解密失败", e);
			// throw new RuntimeException(e);
			return "解密失败";
		}
		return (new String(cipherByte));
	}

	/**
	 * 对16进制字符串进行解密
	 * 
	 * @param in 要解密的数据
	 * @return 返回解密后的 String
	 */
	public String decypt(String in) {
		String out = null;
		try {
			byte[] mid = hex2byte(in);
			out = decyptByte(mid);
		}
		catch (Exception e) {
			throw new RuntimeException("解析失败, 请确认字符串是否加密过的: " + in);
		}
		return out;
	}

	protected String byteTohex(byte[] in) {
		String hexTable = "0123456789ABCDEF";

		StringBuilder sb = new StringBuilder();
		byte b;
		for (int i = 0; i < in.length; i++) {
			b = in[i];
			sb.append(hexTable.charAt(0xf & b >> 4));
			sb.append(hexTable.charAt(b & 0xf));
		}
		return sb.toString();
	}

	protected byte[] hex2byte(String hex) {
		byte[] bts = new byte[hex.length() / 2];
		for (int i = 0; i < bts.length; i++) {
			bts[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
		}
		return bts;
	}

	/**
	 * 实例代码，同时用来加密MyBasicDataSourceFactory中的密码
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		String keyWords = "cn.yesway";// 加密密匙
		DES des = new DES(keyWords);

		/* if (args != null && args.length >= 2) {
			// System.out.println("input:" + args[0] + "/" + args[1]);
			if ("-e".equalsIgnoreCase(args[0])) {
				System.out.println(des.encrypt(args[1]));
			}

			if ("-d".equalsIgnoreCase(args[0])) {
				System.out.println(des.decypt(args[1]));
			}
		}*/
		
		System.out.println(des.encrypt("root"));
	}
}
